﻿using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using System.Web.Script.Serialization;
using System.Reflection;

public class MsgBase 
{
    public string protoName = "null";
    //编码器
    static JavaScriptSerializer Js = new JavaScriptSerializer();
    //编码 序列化 再写入流
    public static byte[] Encode(MsgBase msgBase)
    {
        string s = Js.Serialize(msgBase);
        return System.Text.Encoding.UTF8.GetBytes(s);
    }
    public static byte[] Encode1(MsgBase msgBase)
    {
        string s = JsonConvert.SerializeObject(msgBase, Formatting.None);
        return System.Text.Encoding.UTF8.GetBytes(s);
    }
    //解码 反序列化 把数据流反序列化位字符串 再由字符串反序列化为对象
    public static MsgBase Decode1(string protoName, byte[] bytes, int offset, int count)
    {
        string s = System.Text.Encoding.UTF8.GetString(bytes, offset, count);
        MsgBase msgBase = (MsgBase)Js.Deserialize(s, Type.GetType(protoName));
        return msgBase;
    }
    public static string GetString(MsgBase msgBase)
    {
        return JsonConvert.SerializeObject(msgBase, Formatting.None);
    }
    /// <summary>
    /// 将byte数据利用json反序列化位对象
    /// </summary>
    /// <param name="bytes">要解析得字节流数据</param>
    /// <param name="conut">需要使用得字节数</param>
    /// <returns></returns>
    public static MsgBase Decode1(byte[] bytes, UInt16 conut)
    {
        string s = System.Text.Encoding.UTF8.GetString(bytes, sizeof(UInt16), conut);//这个byte数组前面有长度信息
        //string s = System.Text.Encoding.UTF8.GetString(bytes, 0, conut);
        //MsgBase msgBase1 = JsonConvert.DeserializeObject<MsgBase>(s);
        MsgBase msgBase1 = Js.Deserialize<MsgBase>(s);
        string protoName = msgBase1.protoName;
        MsgBase msgBase = (MsgBase)Js.Deserialize(s, Type.GetType(protoName));
        return msgBase;
    }
    /// <summary>
    /// 将byte数据利用json反序列化为对象
    /// </summary>
    /// <param name="bytes">要解析得字节流数据</param>
    /// <param name="conut">需要使用得字节数</param>
    /// <returns></returns>
    public static MsgBase Decode(byte[] bytes,int idex, UInt16 conut)
    {
        string s = System.Text.Encoding.UTF8.GetString(bytes, idex, conut);
        //MsgBase msgBase1 = JsonConvert.DeserializeObject<MsgBase>(s);
        MsgBase msgBase1 = Js.Deserialize<MsgBase>(s);
        string protoName = msgBase1.protoName;
        #region BUG: 若不同的命名空间存在多个同名类 只会实例化找到的第一个 后面的同名类会被忽略 这主要是和服务端配合改代码
        Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
        Type[] typeArr = assembly.GetTypes();//所有的类名
        for (int i = 0; i < typeArr.Length; i++)
        {
            if (typeArr[i].Name == protoName)
            {
                return (MsgBase)Js.Deserialize(s, Type.GetType(typeArr[i].FullName));
            }
        }
        #endregion
        //MsgBase msgBase = (MsgBase)JsonUtility.FromJson(s, Type.GetType(protoName));
        return null;
    }
    //编码协议名（2字节长度+字符串）
    public static byte[] EncodeName(MsgBase msgBase)
    {
        //名字bytes和长度
        byte[] nameBytes = System.Text.Encoding.UTF8.GetBytes(msgBase.protoName);
        UInt16 len = (UInt16)nameBytes.Length;
        //申请bytes数值
        byte[] bytes = new byte[2 + len];
        //组装2字节的长度信息
        bytes[0] = (byte)(len % 256);
        bytes[1] = (byte)(len / 256);
        //组装名字bytes
        Array.Copy(nameBytes, 0, bytes, 2, len);
        return bytes;
    }
    //解码协议名（2字节长度+字符串）
    public static string DecodeName(byte[] bytes, int offset, out int count)
    {
        count = 0;
        //必须大于2字节
        if (offset + 2 > bytes.Length)
        {
            return "";
        }
        //读取长度
        UInt16 len = (UInt16)((bytes[offset + 1] << 8) | bytes[offset]);
        //长度必须足够
        if (offset + 2 + len > bytes.Length)
        {
            return "";
        }
        //解析
        count = 2 + len;
        string name = System.Text.Encoding.UTF8.GetString(bytes, offset + 2, len);
        return name;
    }
}
